package breakthrough;

import java.util.ArrayList;

public class MoveManager
{
	private static final Player whitePlayer = new Player(Player.WHITE_PLAYER);
	private static final Player bluePlayer = new Player(Player.BLUE_PLAYER);
	
	/**
	 * Generate and return a list of possible boards (successors) from given board and player.
	 * @return List of possible boards.
	 */
	public static ArrayList<Board> getPossibleBoards(Board aBoard, Player aPlayer, Player maxPlayer)
	{
		ArrayList<Board> successors = new ArrayList<Board>();
		
		char [][] boardTable = aBoard.getBoardTable();
		
		for (int row = 0; row < Board.BOARD_WIDTH; row++)
		{
			for (int col = 0; col < Board.BOARD_HEIGTH; col++)
			{
				if (aPlayer.equals(whitePlayer))
				{
					if (boardTable[row][col] == Board.WHITE_PAWN)
					{
						// Left diagonal move.
						if (row + 1 < Board.BOARD_WIDTH && col - 1 >= 0 && boardTable[row + 1][col - 1] != Board.WHITE_PAWN)
							successors.add(makeNewBoard(boardTable, new PawnPosition(row, col), new PawnPosition(row + 1, col - 1), aPlayer, maxPlayer));
						
						// Move ahead.
						if (row + 1 < Board.BOARD_WIDTH && boardTable[row + 1][col] == Board.NULL_PAWN)
							successors.add(makeNewBoard(boardTable, new PawnPosition(row, col), new PawnPosition(row + 1, col), aPlayer, maxPlayer));
	
						
						
						// Right diagonal move.
						if (row + 1 < Board.BOARD_WIDTH && col + 1 < Board.BOARD_HEIGTH && boardTable[row + 1][col + 1] != Board.WHITE_PAWN)
							successors.add(makeNewBoard(boardTable, new PawnPosition(row, col), new PawnPosition(row + 1, col + 1), aPlayer, maxPlayer));
					}
				}
				else if (aPlayer.equals(bluePlayer))
				{
					if (boardTable[row][col] == Board.BLUE_PAWN)
					{
						// Left diagonal move.
						if (row - 1 >= 0 && col - 1 >= 0 && boardTable[row - 1][col - 1] != Board.BLUE_PAWN)
							successors.add(makeNewBoard(boardTable, new PawnPosition(row, col), new PawnPosition(row - 1, col - 1), aPlayer, maxPlayer));
						
						// Move ahead.
						if (row - 1 >= 0 && boardTable[row - 1][col] == Board.NULL_PAWN)
							successors.add(makeNewBoard(boardTable, new PawnPosition(row, col), new PawnPosition(row - 1, col), aPlayer, maxPlayer));
	
						
						
						// Right diagonal move.
						if (row - 1 >= 0 && col + 1 < Board.BOARD_HEIGTH && boardTable[row - 1][col + 1] != Board.BLUE_PAWN)
							successors.add(makeNewBoard(boardTable, new PawnPosition(row, col), new PawnPosition(row - 1, col + 1), aPlayer, maxPlayer));
					}
				}
			}
		}
		
		return successors;
	}
	
	/**
	 * Makes a new table after a move
	 * @param boardTable
	 * @param source
	 * @param destination
	 * @return
	 */
	public static Board makeNewBoard(char [][] boardTable, PawnPosition source, PawnPosition destination, Player aPlayer, Player maxPlayer)
	{	
		char [][] newTable = new char[Board.BOARD_WIDTH][Board.BOARD_HEIGTH];
		char sourceValue = boardTable[source.getRow()][source.getColumn()];
		Move newMove = new Move(source, destination);
		
		for (int row = 0; row < Board.BOARD_WIDTH; row++)
		{
			for (int col = 0; col < Board.BOARD_HEIGTH; col++)
			{
				if (row == source.getRow() && col == source.getColumn())
					newTable[row][col] = Board.NULL_PAWN;
				else if (row == destination.getRow() && col == destination.getColumn())
					newTable[row][col] = sourceValue;
				else
					newTable[row][col] = boardTable[row][col];
			}
		}
		
		// Create a new board with an updated table and the previous table. The previous table will be used in the evaluation function.
		Board newBoard = new Board(newTable, boardTable, newMove);
		
		// Evaluates the new board. That will be necessary for sorting the successors by board value.
		BoardEvaluator.evaluateBoard(newBoard, aPlayer, maxPlayer);
		
		return newBoard;
	}
	
	/**
	 * Checks a move's validity
	 * @param boardTable
	 * @param source
	 * @param destination
	 * @return
	 */
	public static boolean isValidMove(char [][] boardTable, PawnPosition source, PawnPosition destination, Player aPlayer)
	{
		return true;
	}
}
